package managedbean.staff;

import exception.ExistException;
import java.io.IOException;
import java.io.Serializable;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import managedbean.PageRedirectorBean;
import org.primefaces.model.MenuModel;
import session.stateless.StaffAccountSessionBean;
import session.stateless.SystemMessagesBean;
import util.entityhelper.StaffAccountState;
import util.localization.WebLocalization;

@ManagedBean
@RequestScoped
public class StaffLoginManagedBean implements Serializable {

    @EJB
    private StaffAccountSessionBean staffAccountMgr;
    // EXCEPTION
    @EJB
    private SystemMessagesBean systemMessages;
    private FacesContext ctx = FacesContext.getCurrentInstance();
    private WebLocalization localization;
    //  user preferred locale
    private String preferredLocale;
    private PageRedirectorBean redirect;
    // other fields from database
    private String username;
    private String password;
//    private StaffAccountState staffAccountState;
    // other fields
    private boolean remember;
    private String r;
    private MenuModel model;
    private int invalidLoginCount;

    /** Creates a new instance of StaffLoginManagedBean */
    public StaffLoginManagedBean() {
        checkCookie();

        /* LOCALIZATION */
        localization = new WebLocalization();
        preferredLocale = localization.getPreferredLocaleFromSession();
        /* END LOCALIZATION */

        /* pre-load values from session and database */
        // check if already logged in...redirect to tourist view page (home)
        if (ctx.getExternalContext().getSessionMap().containsKey("staffAccountId")) {
            // redirect back to login
            redirect = new PageRedirectorBean();
            redirect.goStaffWelcomePage();
        }

        if (ctx.getExternalContext().getSessionMap().containsKey("invalidLoginCount")) {
            invalidLoginCount = Integer.parseInt(ctx.getExternalContext().getSessionMap().get("invalidLoginCount").toString());
        }
        /* END load values from session and database */
    }

    public void doLogin(ActionEvent event) {
        System.out.println("login count main: " + invalidLoginCount);
        try {
            // set language for all MANAGERS for all THROWABLE EXCEPTIONS in backend
            // to use this line everytime language changes
            staffAccountMgr.setSelectedLocale(preferredLocale);

            StaffAccountState staffAccountState = null;
            try {
                staffAccountState = staffAccountMgr.getStaffAccountByUsername(username);
            } catch (ExistException ex) {
                // EXCEPTION
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ""));
            }

            if (staffAccountState != null) {
                if (staffAccountState.getStatus() == true) {
                    if (staffAccountState.getPassword().equals(password)) {
                        // Save the userid and password in a cookie
                        Cookie usernameCookie = new Cookie("usernameCookie", username);
                        //                    Cookie passwordCookie = new Cookie("passwordCookie", password);
                        if (remember == false) {
                            r = "false";
                        } else {
                            r = "true";
                        }
                        Cookie rememberCookie = new Cookie("rememberCookie", r);
                        usernameCookie.setMaxAge(3600);
                        //                    passwordCookie.setMaxAge(3600);

                        ((HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse()).addCookie(usernameCookie);
                        //                    ((HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse()).addCookie(passwordCookie);
                        ((HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse()).addCookie(rememberCookie);

                        /* LOCALIZATION */
                        // first thing after set cookie is to save details to session! and do whatever required first                        
                        // now after login, replace preferred language with SAVED LANGUAGE in database
                        preferredLocale = staffAccountState.getStaff().getLocale();
                        // set language for related backend MANAGERS for all THROWABLE EXCEPTIONS from now on in
                        // backend if message is not sent from frontend to backend through SystemMessages
                        // to use this line everytime having possible language changes
                        staffAccountMgr.setSelectedLocale(preferredLocale);
                        /* END LOCALIZATION */

                        // check if session has anything..default values if nothing
                        if (ctx.getExternalContext().getSessionMap().isEmpty()) {
                            // create a session if no session created. get whatever user uses currently
                            ctx.getExternalContext().getSession(true);
                            // saved preferredLocale (from database) to session; value used to set values in constructors
                            localization.putSavedLocaleToSession(preferredLocale);
                            ctx.getExternalContext().getSessionMap().put("staffAccountId", staffAccountState.getId());
                        } else {
                            if (FacesContext.getCurrentInstance().getExternalContext().getSessionMap().containsKey("serverPort")) {
                                // if there is a previous session to pass the serverPort, retrieve the server port and destroy then create a new session and place the server port inside.
                                int serverPort = (Integer) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("serverPort");
                                String selectedLocale = "";
                                if (FacesContext.getCurrentInstance().getExternalContext().getSessionMap().containsKey("selectedLocale")) {
                                    selectedLocale = FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("selectedLocale").toString();
                                }
                                // clear previous session
                                FacesContext.getCurrentInstance().getExternalContext().getSessionMap().clear();
                                // create a new session and add the server port.
                                FacesContext.getCurrentInstance().getExternalContext().getSession(true);
                                FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("serverPort", serverPort);
                                FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("selectedLocale", selectedLocale);
                            }
                            // saved preferredLocale (from database) to session; value used to set values in constructors
                            localization.putSavedLocaleToSession(preferredLocale);
                            ctx.getExternalContext().getSessionMap().put("staffAccountId", staffAccountState.getId());
                            ctx.getExternalContext().getSessionMap().put("staffAccessRights", staffAccountState.getAccessRights());
                        }

                        // redirection upon success
                        String serverName = FacesContext.getCurrentInstance().getExternalContext().getRequestServerName();
                        // force normal http
                        int serverPort = (Integer) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("serverPort");
                        // the project name /Tourism-war
                        String contextPath = FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath();
                        // TODO: move to page redirector
                        FacesContext.getCurrentInstance().getExternalContext().redirect("http://" + serverName + ":" + serverPort + contextPath + "/staff/StaffViewAccount.xhtml");
                    } else {
                        if (invalidLoginCount < 3) {
                            System.out.println("invalid count");
                            invalidLoginCount++;
                            System.out.println("login count: " + invalidLoginCount);
                            ctx.getExternalContext().getSessionMap().put("invalidLoginCount", invalidLoginCount);
                            // EXCEPTION
                            String statusMessage = systemMessages.getSystemMessage("LOGIN_INCORRECT", preferredLocale);
                            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, ""));
                        } else {
                            System.out.println("max count");
                            staffAccountState.setStatus(false);
                            staffAccountMgr.updateStatus(staffAccountState);
                            invalidLoginCount = 0;
                            ctx.getExternalContext().getSessionMap().remove("invalidLoginCount");
                            // EXCEPTION
                            //TODO: set in localizedmessage
                            String statusMessage = systemMessages.getSystemMessage("Your account has been lock-out. Please contact admin.", preferredLocale);
                            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, ""));
                        }
                    }
                } // locked-out status
                else {
                    // EXCEPTION
                    //TODO: set in localizedmessage
                    String statusMessage = systemMessages.getSystemMessage("Your account has been locked-out. Please contact admin.", preferredLocale);
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, ""));
                }
            }
        } catch (IOException ex) {
            // EXCEPTION
            String statusMessage = systemMessages.getSystemMessage("REDIRECT_FAIL", preferredLocale);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, ""));
        }
    }

    public void checkCookie() {
        String cookieName = null;
        Cookie cookie[] = ((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest()).getCookies();
        if (cookie != null && cookie.length > 0) {
            for (int i = 0; i < cookie.length; i++) {
                cookieName = cookie[i].getName();
                if (cookieName.equals("usernameCookie")) {
                    username = cookie[i].getValue();
//                } else if (cookieName.equals("passwordCookie")) {
//                    password = cookie[i].getValue();
                } else if (cookieName.equals("rememberCookie")) {
                    r = cookie[i].getValue();
                    if (r.equals("false")) {
                        setRemember(false);
                    } else if (r.equals("true")) {
                        setRemember(true);
                    }
                }
            }
        } else {
            System.out.println("Cannot find any cookie");
        }
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public boolean getRemember() {
        return remember;
    }

    public void setRemember(boolean remember) {
        this.remember = remember;
    }

    public SystemMessagesBean getSystemMessages() {
        return systemMessages;
    }

    public void setSystemMessages(SystemMessagesBean systemMessages) {
        this.systemMessages = systemMessages;
    }

    public StaffAccountSessionBean getStaffAccountMgr() {
        return staffAccountMgr;
    }

    public void setTouristAccountMgr(StaffAccountSessionBean staffAccountMgr) {
        this.staffAccountMgr = staffAccountMgr;
    }

    public FacesContext getCtx() {
        return ctx;
    }

    public void setCtx(FacesContext ctx) {
        this.ctx = ctx;
    }

    public String getPreferredLocale() {
        return preferredLocale;
    }

    public void setPreferredLocale(String preferredLocale) {
        this.preferredLocale = preferredLocale;
    }

    public String getR() {
        return r;
    }

    public void setR(String r) {
        this.r = r;
    }

    public WebLocalization getLocalization() {
        return localization;
    }

    public void setLocalization(WebLocalization localization) {
        this.localization = localization;
    }

    /**
     * @return the model
     */
    public MenuModel getModel() {
        return model;
    }

    /**
     * @param model the model to set
     */
    public void setModel(MenuModel model) {
        this.model = model;
    }
    
}
